home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Carousel
/
CAROUSEL.cdr
/
mactosh
/
hc
/
tex05_sr.sit
/
openCloseTEXFiles 0.5.c
< prev
next >
Wrap
Text File
|
1988-09-04
|
7KB
|
310 lines
/* new HyperCard XFCN to open/close index, context, and text files
* copyright 1988 Mark ^Zimmermann - 880831-0904
*
* Call this XFCN as 'openCloseTEXfiles([optional list of numbers here])'.
*
* If the XFCN is called with no arguments, it puts up the standard files
* dialog box and gives back in return the file refNums for the text
* (document/dataspace) file, *.k, and *.p files, on one line, in
* that order, separated by spaces. Note that the *.k and *.p files
* must be in the same folder as the master dataspace file; an earlier
* version of this XFCN tried to allow them to be elsewhere (or to
* have different names), but it was too complex and didn't seem to be
* appreciated by the users!
*
* If the XFCN is passed any numerical parameters, it attempts to
* close them (assuming they are file refNums) and doesn't try to
* open anything....
*
* If an error while opening a file seems to occur, the XFCN attempts
* to close all files that have already been opened, and returns with
* an error msg instead of the three file refNums. No error checking
* is done on closing files, since there's not much that one could
* do about such an error in any case....
*
*/
#include <MacTypes.h>
#include <FileMgr.h>
#include <StdFilePkg.h>
#include <HyperXCmd.h>
#define NULL 0
/* define these to allow use of global variables in my XFCNs; a
* Lightspeed C necessity, apparently...
*/
#define SetUpA4() asm { move.l a4,-(sp) \
move.l a0,a4 }
#define RestoreA4() asm { move.l (sp)+,a4 }
pascal void main (XCmdBlockPtr paramPtr);
int zGetFile (Str255 *fileNamePtr, int *volRefNumPtr, long fileType);
void returnErrorMsg (XCmdBlockPtr paramPtr, char *msg);
long atol (char *s);
void ltoaR (char *ansp, long n, int maxDigits);
int strlen (char *s);
char *strcpy (char *s1, char *s2);
pascal void main (paramPtr)
XCmdBlockPtr paramPtr;
{
Str255 fileName;
int refNum, volRefNum, textFileRefNum, keyFileRefNum, ptrFileRefNum,
i, errNum;
Handle answer;
SetUpA4();
if (paramPtr->paramCount != 0)
{
for (i = 0; i < paramPtr->paramCount; ++i)
{
refNum = atol (*(paramPtr->params[i]));
FSClose (refNum);
}
RestoreA4();
return;
}
if (! zGetFile (&fileName, &volRefNum, 'TEXT'))
{
RestoreA4();
return;
}
errNum = FSOpen (&fileName, volRefNum, &textFileRefNum);
if (errNum != noErr && errNum != opWrErr)
{
returnErrorMsg (paramPtr,
"{Sorry, error in opening text file!}");
RestoreA4();
return;
}
*(fileName + *fileName + 1) = '.';
*(fileName + *fileName + 2) = 'k';
*fileName += 2;
errNum = FSOpen (&fileName, volRefNum, &keyFileRefNum);
if (errNum != noErr && errNum != opWrErr)
{
FSClose (textFileRefNum);
returnErrorMsg (paramPtr,
"{Sorry, error in opening index key (*.k) file!}");
RestoreA4();
return;
}
*(fileName + *fileName) = 'p';
errNum = FSOpen (&fileName, volRefNum, &ptrFileRefNum);
if (errNum != noErr && errNum != opWrErr)
{
FSClose (textFileRefNum);
FSClose (keyFileRefNum);
returnErrorMsg (paramPtr,
"{Sorry, error in opening index ptr (*.p) file!}");
RestoreA4();
return;
}
if ((answer = NewHandle (20)) == NULL)
{
FSClose (textFileRefNum);
FSClose (keyFileRefNum);
FSClose (ptrFileRefNum);
returnErrorMsg (paramPtr,
"{Sorry, bad out of memory error in XFCN openTEXfiles call!}");
RestoreA4();
return;
}
ltoaR (*answer, textFileRefNum, 6);
ltoaR (*answer + 6, keyFileRefNum, 6);
ltoaR (*answer + 12, ptrFileRefNum, 6);
*(*answer + 18) = '\0';
paramPtr->returnValue = answer;
RestoreA4();
return;
}
/* this routine, adapted from the Lightspeed C 'MiniEdit' example, does
* the standard files dialog routine to get the name of the text file
* of the dataspace; other file names are gotten from that by putting
* a '.k' or a '.p' at the end. This routine returns 1 if all is well,
* or 0 if the user cancels out...
*/
int zGetFile (fileNamePtr, volRefNumPtr, fileType)
Str255 *fileNamePtr;
int *volRefNumPtr;
long fileType;
{
SFTypeList myFileTypes;
Point SFGwhere;
SFReply myReply;
register int i;
SFGwhere.v = 90;
SFGwhere.h = 82;
myFileTypes[0] = fileType;
SFGetFile (SFGwhere, "\p", 0L, 1, myFileTypes, 0L, &myReply);
if (myReply.good)
{
for (i = *myReply.fName; i >= 0; --i)
(*fileNamePtr)[i] = myReply.fName[i];
*volRefNumPtr = myReply.vRefNum;
return (1);
}
else
return (0);
}
/* function to set the return value of the XFCN to a chosen error msg;
* if there isn't enough free memory to give us a Handle to the msg,
* beep a bunch and then return!
*/
void returnErrorMsg (paramPtr, msg)
XCmdBlockPtr paramPtr;
char *msg;
{
Handle answer;
int msgLength;
SysBeep (10);
msgLength = strlen (msg);
if ((answer = NewHandle (1 + msgLength)) == NULL)
{
SysBeep (10);
SysBeep (10);
SysBeep (10);
SysBeep (10);
SysBeep (10);
return;
}
strcpy (*answer, msg);
paramPtr->returnValue = answer;
return;
}
/* function to convert alphanumeric string to a long int, from K&R & LSC
* library.... simplified to avoid using isspace() & isdigit() ....
*/
long atol (s)
register char *s;
{
int signflag = 0;
register long r = 0;
while (*s == ' ')
s++;
if (*s == '-')
{
signflag = 1;
s++;
}
else if (*s == '+')
s++;
while (*s >= '0' && *s <= '9')
r = r * 10 + (*s++ - '0');
return (signflag ? -r : r);
}
/* function to convert a number into a string of width maxDigits and
* store it right-justified, blank-filled on left; based on K&R p. 60
* example of itoa().
*
* Error handling: put a '>' or '<' in leading place to warn of an
* overflow (no room for digits on a positive or negative number,
* respectively), and put a '^' in leading place to warn if no room
* for '-' sign on negative number...
*/
void ltoaR (ansp, n, maxDigits)
register char *ansp;
register long n;
int maxDigits;
{
register int i;
long sign;
i = maxDigits - 1;
if ((sign = n) < 0)
n = -n;
do
{
ansp[i--] = n % 10 + '0';
}
while ((n /= 10) > 0 && i >= 0);
if (i < 0 && n > 0) /* ran out of room with digits still to go */
{
if (sign > 0)
ansp[0] = '>'; /* positive overflow signal */
else
ansp[0] = '<'; /* negative overflow signal */
}
else
{
if (sign < 0)
if (i >= 0)
ansp[i--] = '-';
else
ansp[0] = '^'; /* no room for '-' sign signal */
for ( ; i >= 0; --i)
ansp[i] = ' ';
}
return;
}
/* function to determine the length of a string ... standard thing,
* adapted from the LSC library, and K&R p.98 ....
*/
int strlen (s)
register char *s;
{
char *s0 = s;
while (*s++)
;
return (s - s0 - 1);
}
/* function to copy a string from one place to another, in a rather
* obvious fashion ... adapted from the LSC library, and K&R p.101 ....
*/
char *strcpy (s1, s2)
register char *s1, *s2;
{
char *s = s1;
while (*s1++ = *s2++)
;
return (s);
}